﻿using System.Reflection.Emit;

namespace Aeon.Emulator.Decoding.Recompiler
{
    /// <summary>
    /// Manages allocation of temporary local variables.
    /// </summary>
    internal sealed class TempStorage
    {
        #region Private Fields
        private ILGenerator il;
        private LocalBuilder tempByte;
        private LocalBuilder tempShort;
        private LocalBuilder tempInt;
        private LocalBuilder tempAddress;
        #endregion

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the TempStorage class.
        /// </summary>
        public TempStorage()
        {
        }
        #endregion

        #region Public Properties
        /// <summary>
        /// Gets the temporary byte storage variable.
        /// </summary>
        public LocalBuilder Byte
        {
            get
            {
                if(this.tempByte == null)
                    this.tempByte = il.DeclareLocal(typeof(byte));
                return this.tempByte;
            }
        }
        /// <summary>
        /// Gets the temporary short storage variable.
        /// </summary>
        public LocalBuilder Short
        {
            get
            {
                if(this.tempShort == null)
                    this.tempShort = il.DeclareLocal(typeof(ushort));
                return this.tempShort;
            }
        }
        /// <summary>
        /// Gets the temporary int storage variable.
        /// </summary>
        public LocalBuilder Int
        {
            get
            {
                if(this.tempInt == null)
                    this.tempInt = il.DeclareLocal(typeof(uint));
                return this.tempInt;
            }
        }
        /// <summary>
        /// Gets the temporary address storage variable.
        /// </summary>
        public LocalBuilder Address
        {
            get
            {
                if(this.tempAddress == null)
                    this.tempAddress = il.DeclareLocal(typeof(uint));
                return this.tempAddress;
            }
        }
        #endregion
        
        #region Public Methods
        /// <summary>
        /// Initializes the TempStorage instance against an ILGenerator.
        /// </summary>
        /// <param name="il">ILGenerator to associate with the TempStorage instance.</param>
        public void Initialize(ILGenerator il)
        {
            this.il = il;
            this.tempByte = null;
            this.tempShort = null;
            this.tempInt = null;
            this.tempAddress = null;
        }
        #endregion
    }
}
